package com.my.json;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.my.json.domain.InputXml;
import com.my.json.sensitive.config.SensitiveInfoFastJsonFilter;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * spring默认带的转json包为jackson 替换方式为
 * https://www.jianshu.com/p/a3ebb54445be
 * 目前没有替换
 * fastjson 枚举
 * https://blog.csdn.net/qq_33306246/article/details/106933613
 *
 * FastJson默认配置
 * 2021年3月4日10:13:55 测试通过
 * @author timo 2021/3/3
 */
//影响不了cn.hutool.json 只能管spring的控制器响应和com.alibaba.fastjson.JSON.toJSONString
@Configuration
@ConditionalOnClass(JSON.class)
@Slf4j
public class FastJsonConfiguration {
    static {
        //先执行static代码块，再执行该方法  如果只配置这个，就是只有代码中JSON.toJsonString生效
        //是否输出值为null的字段,默认为false
        JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteMapNullValue.getMask();
        //数值字段如果为null,输出为0,而非null
        JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteNullNumberAsZero.getMask();
        //List字段如果为null,输出为[],而非null
        JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteNullListAsEmpty.getMask();
        //字符类型字段如果为null,输出为 "",而非null
        JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteNullStringAsEmpty.getMask();

        // 新增：禁用Unicode转义，确保中文正常显示
        JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCheckSpecialChar.getMask();
    }
    //- static代码块：影响 所有 使用FastJSON的场景（包括工具类、非HTTP序列化等）
    // - 消息转换器：仅影响 Controller返回值 的JSON序列化
    @Bean
    public HttpMessageConverters fastJsonMessageConverters() {
        List<HttpMessageConverter<?>> converters = new ArrayList<>();
        //需要定义一个convert转换消息的对象;
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        //添加fastJson的配置信息;
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
//                SerializerFeature.PrettyFormat,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteNullStringAsEmpty,
//                SerializerFeature.DisableCircularReferenceDetect,
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.WriteDateUseDateFormat);
        // 添加敏感信息过滤器（新增代码）
        fastJsonConfig.setSerializeFilters(new SensitiveInfoFastJsonFilter());
        //全局时间配置
        fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
        fastJsonConfig.setCharset(Charset.forName("UTF-8"));
        //处理中文乱码问题
//        List<MediaType> fastMediaTypes = new ArrayList<>();
//        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        //3处理中文乱码问题
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.valueOf("application/json;charset=UTF-8"));
        //在convert中添加配置信息.
        fastConverter.setSupportedMediaTypes(fastMediaTypes);
        fastConverter.setFastJsonConfig(fastJsonConfig);

        converters.add(0, fastConverter);
        return new HttpMessageConverters(converters);
    }

    @Test
    public void test3() throws JsonProcessingException {
        InputXml inputXml = new InputXml();
        inputXml.setUserName("郑涛");
        inputXml.setIdCard("asa");
        inputXml.setJybh(null);

        ObjectMapper maskMapper = new ObjectMapper();
        System.out.println(maskMapper.writeValueAsString(inputXml));
//去掉转义符的json字符串。
//        StringEscapeUtils.unescapeJava();
        //没有config的配置时 可以这样转化
        JSONObject.toJSONString(inputXml, SerializerFeature.WriteMapNullValue);

        String s = JSON.toJSONString(inputXml);
        log.info("fastjson--toJSONString:::"+s);
        //SerializerFeature主要是针对Object对象序列化转换时的情况（这个时候才能判断参数的类型），
        //而在Map中，你放进入了null就是null，进行序列化时已经没法判断它原来的类型了，所以并没有起作用。
        //要使用SerializerFeature里相关null的参数，应该传入对象进行序列化
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userName","1212");
        jsonObject.put("jybh",null);
        String s3 = JSON.toJSONString(jsonObject);
        log.info("fastjson-JSONObject--toJSONString:::"+s3);

        cn.hutool.json.JSONObject jsonObject1 = new cn.hutool.json.JSONObject();
        jsonObject1.put("userName","1212");
        jsonObject1.put("jybh",null);

        String s2 = JSONUtil.toJsonStr(inputXml);
        log.info("hutool--toJsonStr :::"+s2);
        String s4 = JSONUtil.toJsonStr(jsonObject1);
        log.info("hutool-JSONObject-toJsonStr :::"+s4);
        JSONConfig jsonConfig = new JSONConfig();
        jsonConfig.setIgnoreNullValue(false);
        cn.hutool.json.JSONObject jsonObject2 = new cn.hutool.json.JSONObject(jsonConfig);
        jsonObject2.put("userName2","12124444");
        jsonObject2.put("jybh2",null);
//        jsonObject2.put("obj",jsonObject);
        String s5= JSONUtil.toJsonStr(jsonObject2);
        log.info("hutool-JSONConfig-JSONObject-toJsonStr :::"+s5);

        String jsonStr = "[{\"id\": \"1\",\"name\": \"a\"},{\"id\": \"2\",\"name\": \"b\"}]";
        final JSONArray jsonArray = JSONUtil.parseArray(jsonStr);
        // 方法1
        jsonArray.getByPath("[1].name");
        // 方法2
        JSONUtil.getByPath(jsonArray, "[1].name");


        String s1 = inputXml.toString();
        log.info("toString :::"+s1);
    }
}
